<template>
  <div class="search-box">
    <!-- 大咖信息编辑抽屉 -->
    <a-drawer v-model:visible="open" width="800px" :title="`${!!searchForm.id ? '编辑' : '新建'}大咖`" :confirmLoading="loading" @cancel="hideModal">
      <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
        <!-- 基本信息区域 -->
        <a-form-item label="大咖姓名" v-bind="validateInfos.name">
          <a-input v-model:value="searchForm.name" placeholder="请输入大咖姓名" />
        </a-form-item>

        <!-- 头像上传区域 -->
        <a-form-item label="大咖头像" v-bind="validateInfos.headImg">
          <upload-image v-model="searchForm.headImg" placeholder="上传大咖头像" :max-size="2" />
        </a-form-item>

        <a-form-item label="大咖说" v-bind="validateInfos.says">
          <a-input v-model:value="searchForm.says" placeholder="请输入大咖说" />
        </a-form-item>

        <!-- 头衔选择区域 -->
        <a-form-item label="头衔" v-bind="validateInfos.titles">
          <tag-selector v-model:tags="titleTags" v-model:input="titleInput" :options="titleDictOptions" placeholder="请选择头衔" @add="(tag) => handleAddTag('titles', tag)" @remove="(index) => handleRemoveTag('titles', index)" />
        </a-form-item>

        <!-- 研究领域选择区域 -->
        <a-form-item label="研究领域" v-bind="validateInfos.researchField">
          <tag-selector v-model:tags="researchTags" v-model:input="researchInput" :options="researchDictOptions" placeholder="请选择研究领域" @add="(tag) => handleAddTag('researchField', tag)" @remove="(index) => handleRemoveTag('researchField', index)" />
        </a-form-item>

        <!-- 医院信息区域 -->
        <a-form-item label="所属医院" v-bind="validateInfos.hospital">
          <a-input v-model:value="searchForm.hospital" placeholder="请输入所属医院" />
        </a-form-item>

        <a-form-item label="所属部门" v-bind="validateInfos.department">
          <a-input v-model:value="searchForm.department" placeholder="请输入所属部门" />
        </a-form-item>

        <a-form-item label="所属科室" v-bind="validateInfos.section">
          <a-input v-model:value="searchForm.section" placeholder="请输入所属科室" />
        </a-form-item>

        <!-- 个人简介富文本编辑器 -->
        <a-form-item label="个人简介" v-bind="validateInfos.personalBrief">
          <vue-ueditor-wrap v-model="searchForm.personalBrief" :config="editorConfig" />
        </a-form-item>
      </a-form>
      <template #footer>
        <a-button style="margin-right: 8px" @click="hideModal">取消</a-button>
        <a-button type="primary" @click="handleOk">提交</a-button>
      </template>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
  import { Form } from 'ant-design-vue'
  import message from 'ant-design-vue/es/message'
  import { onMounted, reactive, ref, toRaw } from 'vue'

  import { requestGetAllDicts, requestSaveBigShot } from '/@/api/exchange/bigShot'
  import { HttpCodeEnum } from '/@/enums/httpEnum'

  import TagSelector from './TagSelector.vue'
  import UploadImage from './UploadImage.vue'
  // 类型定义
  type TagType = 'titles' | 'researchField'

  // 组件事件定义
  const emit = defineEmits<{
    (e: 'reload'): void
  }>()

  // 基础状态
  const open = ref<boolean>(false)
  const loading = ref<boolean>(false)

  // 表单布局配置
  const labelCol = { style: { width: '150px' } }
  const wrapperCol = { span: 14 }

  // 富文本编辑器配置
  const editorConfig = {
    initialFrameWidth: null,
    initialFrameHeight: 320,
    catchRemoteImageEnable: false,
    autoHeightEnabled: false,
    autoSyncData: false,
    autoFloatEnabled: true,
    UEDITOR_HOME_URL: import.meta.env.VITE_PUBLIC_PATH + '/UEditor/',
    toolbars: [['|', 'source', 'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'forecolor', 'backcolor', 'pasteplain', '|', 'insertorderedlist', 'insertunorderedlist', 'fontfamily', 'fontsize', 'paragraph', 'indent', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', 'inserttable', 'touppercase', 'tolowercase', 'imagenone', 'imageleft', 'imageright', 'imagecenter', 'horizontal', 'undo', 'redo']],
  }

  // 表单数据
  const searchForm = reactive<InformationTypes.IAddInformation>({
    id: undefined,
    name: '',
    headImg: '',
    says: '',
    titles: '',
    researchField: '',
    personalBrief: '',
    hospital: '',
    department: '',
    section: '',
  })

  // 表单验证规则
  const rulesRef = reactive({
    name: [
      { required: true, message: '请输入大咖姓名' },
      { pattern: /^(?!\s+$).{1,32}$/, message: '请输入1-32位的有效姓名' },
    ],
    headImg: [{ required: true, message: '请上传大咖头像' }],
    says: [
      { required: true, message: '请输入大咖说' },
      { pattern: /^(?!\s+$)/, message: '请输入有效内容' },
    ],
    titles: [{ required: true, message: '请添加头衔' }],
    researchField: [{ required: true, message: '请添加研究领域' }],
    hospital: [
      { required: true, message: '请输入所属医院' },
      { pattern: /^(?!\s+$)/, message: '请输入有效内容' },
    ],
    department: [
      { required: true, message: '请输入所属部门' },
      { pattern: /^(?!\s+$)/, message: '请输入有效内容' },
    ],
    section: [
      { required: true, message: '请输入所属科室' },
      { pattern: /^(?!\s+$)/, message: '请输入有效内容' },
    ],
    personalBrief: [
      { required: true, message: '请输入个人简介' },
      { pattern: /^(?!\s+$)/, message: '请输入有效内容' },
    ],
  })

  // 表单实例
  const { resetFields, validate, validateInfos } = Form.useForm(searchForm, rulesRef)

  // 标签相关状态
  const titleInput = ref<number>()
  const researchInput = ref<number>()
  const titleTags = ref<string[]>([])
  const researchTags = ref<string[]>([])
  const titleDictOptions = ref<InformationTypes.IDictResponse['values']>([])
  const researchDictOptions = ref<InformationTypes.IDictResponse['values']>([])

  // 获取字典数据
  const getDictData = async () => {
    const [titleRes, researchRes] = await Promise.all([requestGetAllDicts({ type: 'big_shot_titles' }), requestGetAllDicts({ type: 'big_shot_research_field' })])
    titleDictOptions.value = titleRes.responseData.values || []
    researchDictOptions.value = researchRes.responseData.values || []
  }

  // 标签操作方法
  const handleAddTag = (type: TagType, tag: InformationTypes.IDictResponse['values'][0]) => {
    const tags = type === 'titles' ? titleTags : researchTags
    if (tag && !tags.value.find((t) => t === tag.name)) {
      tags.value.push(tag.name)
      updateFormTags(type)
    } else {
      message.warning('已存在')
    }
  }

  // 删除tag
  const handleRemoveTag = (type: TagType, index: number) => {
    const tags = type === 'titles' ? titleTags : researchTags
    tags.value.splice(index, 1)
    updateFormTags(type)
  }

  // 更新tag
  const updateFormTags = (type: TagType) => {
    const tags = type === 'titles' ? titleTags : researchTags
    if (!tags.value.length) {
      searchForm[type] = ''
      return
    }
    searchForm[type] = JSON.stringify(tags.value)
  }

  // 弹窗操作方法
  const showModal = (info?: InformationTypes.IResponse) => {
    resetFields()
    resetTags()
    if (info) {
      Object.assign(searchForm, info)
      initializeTags(info)
    } else {
      resetTags()
    }
    open.value = true
  }

  const hideModal = () => {
    resetFields()
    resetTags()
    open.value = false
    loading.value = false
  }

  // 初始化数据
  const resetTags = () => {
    titleTags.value = []
    researchTags.value = []
    titleInput.value = undefined
    researchInput.value = undefined
  }

  // 初始化tag
  const initializeTags = (info: InformationTypes.IResponse) => {
    try {
      if (info.titles) {
        titleTags.value = JSON.parse(info.titles)
      }
      if (info.researchField) {
        researchTags.value = JSON.parse(info.researchField)
      }
    } catch (error) {}
  }

  // 更新大咖
  const updateBigShot = async () => {
    return await requestSaveBigShot({
      ...toRaw(searchForm),
    })
  }

  // 提交表单
  const handleOk = async () => {
    try {
      await validate()
      loading.value = true
      const { responseCode } = await updateBigShot()
      if (responseCode === HttpCodeEnum.SUCCESS) {
        message.success('操作成功')
        hideModal()
        emit('reload')
      }
    } catch (error) {
    } finally {
      loading.value = false
    }
  }

  // 生命周期钩子
  onMounted(() => {
    getDictData()
  })

  // 暴露方法
  defineExpose({
    showModal,
  })
</script>

<style lang="less" scoped>
  .search-box {
    .avatar-uploader {
      :deep(.ant-upload) {
        width: 200px;
        height: 120px;
      }
    }

    .tag-input-wrapper {
      .tag-list {
        margin-top: 8px;

        .ant-tag {
          margin-bottom: 8px;
        }
      }

      .input-group {
        display: flex;
        gap: 8px;

        .ant-select {
          flex: 1;
        }
      }
    }
  }
</style>
